package com.zhentao.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zhentao.constant.RedisKeyConstants;
import com.zhentao.dto.MatchmakerQueryDTO;
import com.zhentao.entity.Matchmaker;
import com.zhentao.mapper.MatchmakerMapper;
import com.zhentao.service.MatchmakerService;
import com.zhentao.util.MinioUtil;
import com.zhentao.vo.MatchmakerVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.Period;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * 红娘服务实现类（带Redis缓存）
 */
@Service
public class MatchmakerServiceImpl extends ServiceImpl<MatchmakerMapper, Matchmaker> implements MatchmakerService {
    
    @Autowired
    private MatchmakerMapper matchmakerMapper;
    
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    
    @Autowired
    private MinioUtil minioUtil;
    
    @Override
    @SuppressWarnings("unchecked")
    public Page<MatchmakerVO> getMatchmakerPage(MatchmakerQueryDTO queryDTO) {
        // 1. 构建缓存Key
        String cacheKey = RedisKeyConstants.buildMatchmakerListKey(
                queryDTO.getMatchmakerType(),
                queryDTO.getLevel(),
                queryDTO.getProvinceId(),
                queryDTO.getCityId(),
                queryDTO.getPageNum(),
                queryDTO.getPageSize()
        );
        
        // 2. 尝试从Redis获取缓存（带异常处理）
        try {
            Page<MatchmakerVO> cachedPage = (Page<MatchmakerVO>) redisTemplate.opsForValue().get(cacheKey);
            if (cachedPage != null) {
                System.out.println("✅ 从Redis缓存获取红娘列表: " + cacheKey);
                return cachedPage;
            }
        } catch (Exception e) {
            System.err.println("⚠️ Redis读取失败，将直接查询数据库: " + e.getMessage());
        }
        
        // 3. 缓存未命中或Redis异常，从数据库查询
        System.out.println("❌ 缓存未命中或Redis异常，从数据库查询: " + cacheKey);
        Page<MatchmakerVO> page = new Page<>(queryDTO.getPageNum(), queryDTO.getPageSize());
        
        Page<MatchmakerVO> result = matchmakerMapper.selectMatchmakerPage(
                page,
                queryDTO.getMatchmakerType(),
                queryDTO.getLevel(),
                queryDTO.getProvinceId(),
                queryDTO.getCityId(),
                queryDTO.getKeyword(),
                queryDTO.getOrderBy(),
                queryDTO.getOrderType()
        );
        
        // 4. 处理数据
        result.getRecords().forEach(this::processMatchmakerVO);
        
        // 5. 尝试存入Redis缓存（带异常处理）
        try {
            redisTemplate.opsForValue().set(
                    cacheKey, 
                    result, 
                    RedisKeyConstants.MATCHMAKER_LIST_EXPIRE, 
                    TimeUnit.SECONDS
            );
            System.out.println("💾 红娘列表已缓存到Redis: " + cacheKey);
        } catch (Exception e) {
            System.err.println("⚠️ Redis写入失败，但不影响查询结果: " + e.getMessage());
        }
        
        return result;
    }
    
    @Override
    public MatchmakerVO getMatchmakerDetail(Integer matchmakerId) {
        // 1. 构建缓存Key
        String cacheKey = RedisKeyConstants.buildMatchmakerDetailKey(matchmakerId);
        
        // 2. 尝试从Redis获取缓存（带异常处理）
        try {
            MatchmakerVO cachedVO = (MatchmakerVO) redisTemplate.opsForValue().get(cacheKey);
            if (cachedVO != null) {
                System.out.println("✅ 从Redis缓存获取红娘详情: " + cacheKey);
                return cachedVO;
            }
        } catch (Exception e) {
            System.err.println("⚠️ Redis读取失败，将直接查询数据库: " + e.getMessage());
        }
        
        // 3. 缓存未命中或Redis异常，从数据库查询
        System.out.println("❌ 缓存未命中或Redis异常，从数据库查询: " + cacheKey);
        MatchmakerVO matchmakerVO = matchmakerMapper.selectMatchmakerDetail(matchmakerId);
        
        if (matchmakerVO != null) {
            // 4. 处理数据
            processMatchmakerVO(matchmakerVO);
            
            // 5. 尝试存入Redis缓存（带异常处理）
            try {
                redisTemplate.opsForValue().set(
                        cacheKey, 
                        matchmakerVO, 
                        RedisKeyConstants.MATCHMAKER_DETAIL_EXPIRE, 
                        TimeUnit.SECONDS
                );
                System.out.println("💾 红娘详情已缓存到Redis: " + cacheKey);
            } catch (Exception e) {
                System.err.println("⚠️ Redis写入失败，但不影响查询结果: " + e.getMessage());
            }
        }
        
        return matchmakerVO;
    }
    
    @Override
    @SuppressWarnings("unchecked")
    public Page<MatchmakerVO> getFormalMatchmakers(Integer pageNum, Integer pageSize) {
        // 1. 构建缓存Key
        String cacheKey = RedisKeyConstants.buildFormalListKey(pageNum, pageSize);
        
        // 2. 尝试从Redis获取缓存（带异常处理）
        try {
            Page<MatchmakerVO> cachedPage = (Page<MatchmakerVO>) redisTemplate.opsForValue().get(cacheKey);
            if (cachedPage != null) {
                System.out.println("✅ 从Redis缓存获取全职红娘列表: " + cacheKey);
                return cachedPage;
            }
        } catch (Exception e) {
            System.err.println("⚠️ Redis读取失败，将直接查询数据库: " + e.getMessage());
        }
        
        // 3. 缓存未命中或Redis异常，查询数据库
        System.out.println("❌ 缓存未命中或Redis异常，从数据库查询: " + cacheKey);
        MatchmakerQueryDTO queryDTO = new MatchmakerQueryDTO();
        queryDTO.setMatchmakerType(2); // 2-全职
        queryDTO.setPageNum(pageNum);
        queryDTO.setPageSize(pageSize);
        queryDTO.setOrderBy("success_couples");
        queryDTO.setOrderType("desc");
        
        Page<MatchmakerVO> result = getMatchmakerPage(queryDTO);
        
        // 4. 尝试单独缓存全职红娘列表（带异常处理）
        try {
            redisTemplate.opsForValue().set(
                    cacheKey, 
                    result, 
                    RedisKeyConstants.MATCHMAKER_HOT_EXPIRE, 
                    TimeUnit.SECONDS
            );
            System.out.println("💾 全职红娘列表已缓存到Redis: " + cacheKey);
        } catch (Exception e) {
            System.err.println("⚠️ Redis写入失败，但不影响查询结果: " + e.getMessage());
        }
        
        return result;
    }
    
    /**
     * 处理红娘VO数据
     * 
     * @param vo 红娘VO
     */
    private void processMatchmakerVO(MatchmakerVO vo) {
        // 计算年龄
        if (vo.getBirthDate() != null) {
            LocalDate now = LocalDate.now();
            Period period = Period.between(vo.getBirthDate(), now);
            vo.setAge(period.getYears());
        }
        
        // 设置性别名称
        if (vo.getGender() != null) {
            vo.setGenderName(vo.getGender() == 1 ? "男" : "女");
        }
        
        // 设置类型名称
        if (vo.getMatchmakerType() != null) {
            vo.setTypeName(vo.getMatchmakerType() == 1 ? "兼职红娘" : "全职红娘");
        }
        
        // 设置等级名称
        if (vo.getLevel() != null) {
            switch (vo.getLevel()) {
                case 1:
                    vo.setLevelName("青铜红娘");
                    break;
                case 2:
                    vo.setLevelName("白银红娘");
                    break;
                case 3:
                    vo.setLevelName("黄金红娘");
                    break;
                case 4:
                    vo.setLevelName("铂金红娘");
                    break;
                case 5:
                    vo.setLevelName("钻石红娘");
                    break;
                default:
                    vo.setLevelName("青铜红娘");
            }
        }
        
        // 拼接完整地址
        StringBuilder fullAddress = new StringBuilder();
        if (vo.getProvinceName() != null) {
            fullAddress.append(vo.getProvinceName());
        }
        if (vo.getCityName() != null) {
            fullAddress.append(vo.getCityName());
        }
        if (vo.getAreaName() != null) {
            fullAddress.append(vo.getAreaName());
        }
        if (vo.getAddressDetail() != null) {
            fullAddress.append(vo.getAddressDetail());
        }
        vo.setFullAddress(fullAddress.toString());
        
        // 从MinIO获取头像URL（降低数据库查询压力）
        // 数据库中的avatar_url字段可以存储文件名，如：红娘1.jpg
        if (vo.getAvatarUrl() != null && !vo.getAvatarUrl().isEmpty()) {
            // 如果数据库存储的是完整URL（http开头），直接使用
            if (vo.getAvatarUrl().startsWith("http")) {
                // 保持原URL不变
            } else {
                // 如果是文件名，从MinIO获取访问URL
                String minioUrl = minioUtil.getMatchmakerAvatarUrl(vo.getMatchmakerId(), vo.getAvatarUrl());
                vo.setAvatarUrl(minioUrl);
            }
        } else {
            // 数据库没有存储文件名，尝试根据红娘ID自动匹配
            String minioUrl = minioUtil.getMatchmakerAvatarUrlById(vo.getMatchmakerId());
            vo.setAvatarUrl(minioUrl);
        }
    }
    
    /**
     * 清除红娘相关缓存（用于数据更新时）
     * 
     * @param matchmakerId 红娘ID，如果为null则只清除列表缓存
     */
    public void clearMatchmakerCache(Integer matchmakerId) {
        try {
            // 如果有matchmakerId，清除红娘详情缓存
            if (matchmakerId != null) {
                String detailKey = RedisKeyConstants.buildMatchmakerDetailKey(matchmakerId);
                redisTemplate.delete(detailKey);
                System.out.println("🗑️ 已清除红娘详情缓存: matchmakerId=" + matchmakerId);
            }
            
            // 清除列表缓存（使用模糊匹配删除）
            Set<String> listKeys = redisTemplate.keys(RedisKeyConstants.MATCHMAKER_LIST + "*");
            if (listKeys != null && !listKeys.isEmpty()) {
                redisTemplate.delete(listKeys);
                System.out.println("🗑️ 已清除红娘列表缓存: " + listKeys.size() + " 个");
            }
            
            // 清除全职红娘列表缓存
            Set<String> formalKeys = redisTemplate.keys(RedisKeyConstants.MATCHMAKER_FORMAL_LIST + "*");
            if (formalKeys != null && !formalKeys.isEmpty()) {
                redisTemplate.delete(formalKeys);
                System.out.println("🗑️ 已清除全职红娘列表缓存: " + formalKeys.size() + " 个");
            }
            
            System.out.println("✅ 缓存清除完成");
        } catch (Exception e) {
            System.err.println("⚠️ 清除Redis缓存失败，但不影响数据更新: " + e.getMessage());
        }
    }
}
